package cn.echo.consul.manager.service.impl;

import cn.echo.consul.manager.entity.KeyValueRecord;
import cn.echo.consul.manager.entity.ProjectInfo;
import cn.echo.consul.manager.entity.UserInfo;
import cn.echo.consul.manager.entity.UserPermission;
import cn.echo.consul.manager.entity.vo.ProjectInfoVo;
import cn.echo.consul.manager.entity.vo.UserPermissionVo;
import cn.echo.consul.manager.enums.PermissionRole;
import cn.echo.consul.manager.exception.BizServiceException;
import cn.echo.consul.manager.repository.ManagerRepository;
import cn.echo.consul.manager.service.ProjectInfoService;
import cn.echo.consul.manager.service.UserInfoService;
import cn.echo.consul.manager.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

import static cn.echo.consul.manager.response.ResultCode.*;

/**
 * 项目服务实现类
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class ProjectInfoServiceImpl implements ProjectInfoService {

    final ManagerRepository managerRepository;
    final UserInfoService userInfoService;

    final String projectKeyPrefix = "manager/project/";

    @Value("${manager.consul.envs}")
    private String[] envs;

    /**
     * 获取环境列表
     */
    public List<String> getEnvs() {
        return Arrays.asList(envs);
    }

    /**
     * 获取用户有权限项目列表
     * @return
     */
    public List<ProjectInfoVo> getProjects(String userId, String searchKey) {
        if (StringUtils.isEmpty(userId)) {
            //用户ID不为空
            throw new BizServiceException(F11607);
        }
        List<ProjectInfo> results = managerRepository.getList(projectKeyPrefix, ProjectInfo.class);
        //如果是超管，直接显示所有项目
        Boolean isAdmin = userInfoService.getUserIsAdmin(userId);

        List<ProjectInfoVo> projects = new ArrayList<>(results.size());
        for (ProjectInfo project: results) {
            ProjectInfoVo projectInfoVo = this.convertToInfoVo(userId, project);
            if (isAdmin || projectInfoVo.getRole()!=null) {
                projects.add(projectInfoVo);
            }
        }
        projects.sort(Comparator.comparing(ProjectInfoVo::getRole, Comparator.nullsLast(Comparator.reverseOrder()))
                                .thenComparing(ProjectInfoVo::getProjectId));
        return projects;
    }

    /**
     * 获取项目信息
     * @return
     */
    public ProjectInfoVo getProject(String userId, String projectId) {
        if (StringUtils.isEmpty(userId)) {
            //用户ID不为空
            throw new BizServiceException(F11607);
        }
        ProjectInfo project = this.getUserProject(projectId);
        if (project==null) {
            //项目不存在
            throw new BizServiceException(F11623);
        }
        ProjectInfoVo projectVo = this.convertToInfoVo(userId, project);
        return projectVo;
    }

    /**
     * 项目信息转换为展示模式
     */
    private ProjectInfoVo convertToInfoVo(String userId, ProjectInfo project) {
        ProjectInfoVo projectVo = new ProjectInfoVo();
        projectVo.setProjectId(project.getProjectId());
        projectVo.setProjectDesc(project.getProjectDesc());
        projectVo.setUsable(project.getUsable());
        projectVo.setEnvs(project.getEnvs());
        projectVo.setOwnerId(project.getOwnerId());
        projectVo.setUserId(userId);

        List<UserPermissionVo> permissionVos = new ArrayList<>(project.getUserPermissions().size());
        projectVo.setUserPermissions(permissionVos);

        Iterator<UserPermission> iterator = project.getUserPermissions().iterator();
        while (iterator.hasNext()) {
            UserPermission permission = iterator.next();
            UserInfo userInfo = userInfoService.getUserInfo(permission.getUserId());
            //用户不存在就不显示
            if (userInfo==null || !userInfo.getUsable()) {
                iterator.remove();
                continue;
            }
            //设置用户信息
            UserPermissionVo permissionVo = new UserPermissionVo();
            permissionVo.setUserName(userInfo.getUserName());
            permissionVo.setUserId(permission.getUserId());
            permissionVo.setRole(permission.getRole());
            permissionVo.setAuthorId(permission.getAuthorId());
            permissionVo.setAuthorDate(permission.getAuthorDate());
            permissionVos.add(permissionVo);

            //获取自己权限
            if (userId.equals(permission.getUserId())) {
                projectVo.setRole(permission.getRole());
            }
        }
        return projectVo;
    }

    /**
     * 添加项目信息
     */
    public void appendProject(String userId, String projectId, String projectDesc, List<String> envs) {

        ProjectInfo project = this.getUserProject(projectId);
        if (project!=null) {
            //项目已存在
            throw new BizServiceException(F11624);
        }
        Date currDate = new Date();
        project = new ProjectInfo();
        project.setProjectId(projectId);
        project.setProjectDesc(projectDesc);
        project.setOwnerId(userId);
        project.setEnvs(envs);
        project.setUsable(true);
        project.setCreatorId(userId);
        project.setCreatedDate(currDate);
        //添加用户权限信息
        List<UserPermission> permissions = new ArrayList<UserPermission>(){{
            UserPermission permission = new UserPermission();
            permission.setUserId(userId);
            permission.setProjectId(projectId);
            permission.setRole(PermissionRole.OWNER);
            permission.setAuthorId(userId);
            permission.setAuthorDate(currDate);
            add(permission);
        }};
        project.setUserPermissions(permissions);

        managerRepository.update(projectKeyPrefix + projectId, project);
    }

    /**
     * 修改项目信息
     */
    public void modifyProject(String userId, String projectId, String projectDesc, Boolean usable, List<String> envs) {
        ProjectInfo project = this.getUserProject(projectId);
        if (project==null) {
            //项目不存在
            throw new BizServiceException(F11623);
        }
        Date currDate = new Date();
        project.setProjectId(projectId);
        project.setProjectDesc(projectDesc);
        project.setEnvs(envs);
        project.setUpdaterId(userId);
        project.setUpdatedDate(currDate);
        if (usable!=null) {
            project.setUsable(usable);
        }
        managerRepository.update(projectKeyPrefix + projectId, project);
    }

    /**
     * 设置项目的用户权限
     */
    public void modifyUserPermission(String userId, String projectId, PermissionRole role, String authorId) {
        if (authorId.equals(userId)) {
            throw new BizServiceException(F11621);
        }
        UserInfo userInfo = userInfoService.getUserInfo(userId);
        if (userInfo==null || !userInfo.getUsable()) {
            throw new BizServiceException(F11610);
        }
        ProjectInfo project = this.getUserProject(projectId);
        if (project==null) {
            //项目不存在
            throw new BizServiceException(F11623);
        }
        Date currDate = new Date();
        UserPermission userPermission = null;
        for (UserPermission permission: project.getUserPermissions()) {
            if (userId.equals(permission.getUserId())) {
                userPermission = permission;
                userPermission.setRole(role);
                userPermission.setAuthorId(authorId);
                userPermission.setAuthorDate(currDate);
                break;
            }
        }
        if (userPermission==null) {
            userPermission = new UserPermission();
            userPermission.setUserId(userId);
            userPermission.setProjectId(projectId);
            userPermission.setRole(role);
            userPermission.setAuthorId(authorId);
            userPermission.setAuthorDate(currDate);
            project.getUserPermissions().add(userPermission);
        }
        managerRepository.update(projectKeyPrefix + projectId, project);
    }

    /**
     * 移除项目的用户权限
     */
    public void removeUserPermission(String authorId, String userId, String projectId) {
        if (authorId.equals(userId)) {
            throw new BizServiceException(F11621);
        }
        ProjectInfo project = this.getUserProject(projectId);
        Iterator<UserPermission> iterator = project.getUserPermissions().iterator();
        while (iterator.hasNext()) {
            UserPermission permission = iterator.next();
            if (permission.getUserId().equals(userId)) {
                iterator.remove();
                break;
            }
        }
        managerRepository.update(projectKeyPrefix + projectId, project);
    }

    /**
     * 获取项目信息
     */
    private ProjectInfo getUserProject(String projectId) {
        if (StringUtils.isEmpty(projectId) || !StringUtil.isCode(projectId)) {
            //项目编号格式错误
            throw new BizServiceException(F11622);
        }
        ProjectInfo project = managerRepository.get(projectKeyPrefix + projectId, ProjectInfo.class);
        return project;
    }

    /**
     * 获取用户所在项目角色
     */
    public PermissionRole getUserPermission(String userId, String projectId) {
        if (StringUtils.isEmpty(userId)) {
            return null;
        }
        ProjectInfo project = managerRepository.get(projectKeyPrefix + projectId, ProjectInfo.class);
        if (project==null || project.getUserPermissions()==null) {
            return null;
        }
        PermissionRole role = null;
        for (UserPermission permission: project.getUserPermissions()) {
            if (userId.equals(permission.getUserId())) {
                role = permission.getRole();
            }
        }
        return role;
    }
}
